#include "texture.h"
#include "texturemanager.h"
#include <engine/enginebase.h>
#include <ksdef.h>
#include <engine/file.h>

//! declare namespace
namespace 
{
	struct _LoadParam
	{
		_LoadParam(){}
		_LoadParam(const _LoadParam& c) : uSize(c.uSize)
		{
			pData.reset(const_cast<_LoadParam&>(c).pData.release());
		}

		std::auto_ptr<byte> pData;
		uint uSize;
	};
}	// end of namespace 

Texture::Texture(Handle nHandle, const String& strName, bool bManual,
	ResourceManager* pMgr, ManualLoader* pLoader,  ResourceReleaser* pReleaser)
	: Resource(nHandle, strName, emTYPE_TEXTURE, bManual, pMgr, pLoader, pReleaser)
	, m_cSize(0, 0)
	, m_emFormat(emPIXEL_A8R8G8B8)
	, m_emPool(emPOOL_MANAGED)
	, m_emUsage(emTEXTUREUSAGE_DEFAULT)
{	}

Texture::~Texture()
{
}

bool Texture::HasAlpha() const
{
	return m_emFormat == emPIXEL_A8R8G8B8 || m_emFormat == emPIXEL_A8L8;
}

bool Texture::UpdateRegion(const KPoint2& cDest,
	const byte* pMem, const KSize& cSize,
	int nPitch, PixelFormat emFormat)
{
	return UpdateImpl(cDest, pMem, cSize, nPitch, emFormat);
}

int Texture::CalculateSize() const
{
	return 0;
}

Any Texture::PrepareImpl(bool bBackGround)
{
	if (false == IsManual())
	{
		IFile* pFile = g_OpenFile(m_strName.c_str(), false, false, false);
		if (NULL == pFile)
			return Any();

		_LoadParam param;
		param.uSize = pFile->Size();
		param.pData.reset(new byte[param.uSize]);
		pFile->Read(param.pData.get(), param.uSize);
		pFile->Release();
		return Any(param);
	}
	return Any();
}

bool Texture::LoadImpl(const Any& data)
{
	if (IsManual())
	{
		if (data.empty())
			return false;
		
		_LoadParam* pParam = any_cast<_LoadParam*>(data);
		return LoadMemoryImpl(pParam->pData.get(), pParam->uSize);
	}
	
	return CreateInternalImpl();
}

bool Texture::UnLoadImpl()
{
	return DestroyInternalImpl();
}
